package com.weds.data_sync.config.typehandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description mybatis List 类型处理器
 * @Author lihw
 * @Date 2024/1/3 14:28
 */
@MappedJdbcTypes({JdbcType.ARRAY})
@MappedTypes({List.class})
public class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        Array array = null;
        if (!(Objects.isNull(parameter) || parameter.isEmpty())) {
            T t = parameter.get(0);
            if (t instanceof Integer) {
                array = ps.getConnection().createArrayOf(JdbcType.INTEGER.name(), parameter.toArray(new Object[0]));
            } else if (t instanceof Long) {
                array = ps.getConnection().createArrayOf(JdbcType.BIGINT.name(), parameter.toArray(new Object[0]));
            } else {
                array = ps.getConnection().createArrayOf(JdbcType.VARCHAR.name(), parameter.toArray(new Object[0]));
            }

        }
        ps.setArray(i, array);

    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {

        return this.getArray(rs.getArray(columnName));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.getArray(rs.getArray(columnIndex));
    }

    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.getArray(cs.getArray(columnIndex));
    }

    private List<T> getArray(Array array) throws SQLException {
        if (array == null) {
            return new ArrayList<>();
        }
        T[] result = (T[]) array.getArray();
        return Arrays.stream(result).collect(Collectors.toList());
    }
}
